#!/usr/bin/python

import socket,traceback
import os,time
import json
import threading
from Queue import Queue
from Connection import Child_sock
from Dev_state import Dev


"""
host = ''
port = 50000
"""
host = ''
port = 50000
DATA ={}
date1 = Dev("Qingluan","on").getDeviceInformation()
date2 = Dev("Ouyang","off").getDeviceInformation()
date3 = Dev("dev","off").getDeviceInformation()

DATA['Qingluan'] = date1
DATA['Ouyang'] = date2
DATA['dev'] = date3
lock_state = 1
lock = threading.Condition()

class Json_sock(threading.Thread):
    def __init__(self,host,port):
        print "initializing ......network"
        try:
            self.sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            self.sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
            self.sock.bind((host,port))
            self.sock.listen(10)
        except socket.error, e:
            print "Network initialized ...faild:  %s" %e
        except socket.gaierror,e:
            print "Address-related error connecting....: %s" %e
        time.sleep(0.3)
        print "Network initialized ...ok\nThread initializing ..."
        time.sleep(0.3)
        threading.Thread.__init__(self)
        
        print "initializing ... ok"
        global DATA
        print "Data loading ...ok"
        print "Data encoding ...ok"
        os.system("clear")
        print "Listening..."
        self.connect_times = 0
    def run(self):
        while True:
            global lock_state
            lock.acquire()
            print "MAIN"
            self.json_data = self.encode_json(DATA)
            lock_state = 1
            self.connect_times += 1
            print "position top"
            print "now : data : " ,self.json_data
            print "Now : ",time.ctime()
            print "\ttimes : %d"%self.connect_times
            print "lock state :",lock_state
            try:
                
                clientsock,clientaddr = self.sock.accept()
                time.sleep(0.3)
                print "Connected to client ...ok"
                    #clientsock.timeout(10)
                try:
                    if (clientsock.getpeername() != None):
                        print "Got connection from : " ,clientsock.getpeername()
                    else:
                        continue
                    while True:
                        response_to_client = self.json_data
                        if clientsock.getpeername():
                            print "send data to " ,clientsock.getpeername()
                            print response_to_client
                            response_to_client+= "\n"
                            clientsock.sendall(response_to_client)
                            print "send ...ok"
                        else :
                            continue
                        print "check ...connecting", 
                        Ensuredata = clientsock.recv(4096)
                        print Ensuredata
                        if Ensuredata == "ok" and lock_state == 1:
                            for i in range(6):
                                time.sleep(0.3)
                                print ".",
                            print "sucessful\n"
                            print lock_state
                            clientsock.close()
                            lock.wait()
                        elif Ensuredata == "stop":
                            
                            print "this is error\n"
                        else:
                            print "error pointer"
                            continue
                       
                        print "re-initializing ...",
                        """try:
                            clientsock.close()
                            print "sucessful stop Byb"
                        except KeyboardInterrupt:
                            pass
                        except IOError :
                            clientsock.close()
                            print "error disconnect"
                            traceback.print_exc()
                            """
                        print "Connecting" ,clientsock.getpeername()," stop"

                        clientsock.close()
                           
                except KeyboardInterrupt:
                    print traceback.print_exc()
                    print "error herer"
                    clientsock.close()
                    exit(0)
                
            except (KeyboardInterrupt,SystemExit):
                raise
            except IOError:
                print "MAIN Client disconnected"
                traceback.print_exc()
            lock.release()

    def talk_json(self,client):
        if client != None:
            temp = client.recv(4096)
            print "new:", temp
            return self.parase_json(temp)
        else :
            pass

    def parase_json(self,json_obj):
        obj = Json_decoder().decode(json_obj)
        return obj
    def encode_json(self,obj):
        json_obj = Json_encoder().encode(obj)
        return json_obj

class Talking_server(threading.Thread):
    def __init__(self,host,port):
        threading.Thread.__init__(self)
        self.host = host
        self.port = port +1
    def run(self):
        global lock_state
        global DATA
        lock.acquire()
        print "CHILD"
        if lock_state == 1:
            talking = Child_sock(self.host,self.port,DATA)
            a = 0 
            a = talking.run()
            DATA = talking.Upstack()
            print DATA
            #if a == "no":
            lock_state = 0
            lock.notify()
            print "unlock "
        elif lock_state == 0:
            print "Talking lock"
            lock.wait()
        print "lock state :",lock_state
        print "position :second"
        lock.release()
        

        

class Json_encoder(json.JSONEncoder):
    def default(self,obj):
        d = {}
        d['__class__'] = obj.__class__.__name__
        d['__module__'] = obj.__module__
        d.update(obj.__dict__)
        return d

class Json_decoder(json.JSONDecoder):
    def __init__(self):
        json.JSONDecoder.__init__(self,object_hook=self.dict2object)
    def dict2object(self,d):
        if '__class__' in d:
            class_name = d.pop('__class__')
            module_name = d.pop('__module__')
            module = __import__(module_name)
            class_ = getattr(module,class_name)
            args = dict((key.encode('ascii') ,value) for key,value in d.items())
            inst = class_(**args)
        else:
            inst = d
        return inst



if __name__ =="__main__":
    checking_server = Json_sock(host,port)
    talking_server = Talking_server(host,port)
    checking_server.start()
    print
    print "--------*--------"*2
    while True:
        talking_server.run()
        print "---------Q-------"*2
        
    """test_data = Dev("first","off").getDeviceInformation()
    p = Json_encoder().encode(test_data)
    print type(p),"||",p

    o = Json_decoder().decode(p)
    print type(o),"||",o
"""
